package part11singleton;

import java.lang.reflect.Constructor;

/**
 * @description: 单实例防止反射破坏，但是再次被破坏
 * @author: zhang hang
 * @date: 2024/3/24 14:37.
 * @version: 1.0
 */
public class SingletonTest06 {
    private static volatile SingletonTest06 singletonTest06;

    private SingletonTest06() {
        synchronized (SingletonTest06.class) {
            if (singletonTest06 != null) {
                throw new RuntimeException("不要试图用反射破坏单例模式");
            }
        }
    }

    public static SingletonTest06 getInstance() {
        if (singletonTest06 == null) {
            synchronized (SingletonTest06.class) {
                if (singletonTest06 == null) {
                    singletonTest06 = new SingletonTest06();
                }
            }
        }
        return singletonTest06;
    }

    // 防止反射破坏单例模式
    public static void main01(String[] args) {
        try {
            SingletonTest06 singletonTest0601 = SingletonTest06.getInstance();
            Constructor<SingletonTest06> declaredConstructor = SingletonTest06.class.getDeclaredConstructor(null);
            declaredConstructor.setAccessible(true);
            SingletonTest06 singletonTest0602 = declaredConstructor.newInstance();
            System.out.println(singletonTest0601.hashCode());
            System.out.println(singletonTest0602.hashCode());
            System.out.println(singletonTest0601 == singletonTest0602);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 反射再次破坏单例模式
    public static void main(String[] args) {
        try {
            Constructor<SingletonTest06> declaredConstructor = SingletonTest06.class.getDeclaredConstructor(null);
            declaredConstructor.setAccessible(true);
            SingletonTest06 lazyMan1 = declaredConstructor.newInstance();
            SingletonTest06 lazyMan2 = declaredConstructor.newInstance();
            System.out.println(lazyMan1.hashCode());
            System.out.println(lazyMan2.hashCode());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
